package com.redhat.auth.log.common;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redhat.auth.log.annotation.QueryValueType;
import com.redhat.auth.log.annotation.ValueType;
import com.redhat.auth.log.parse.ObjectValueReflection;
import com.redhat.auth.log.parse.SpecialValue;

/**
 * 本类存储5大值来源
 * 
 * @author lingen.liu
 * 
 */
public class CacheDataValue {

	private static final Logger	logger  = LoggerFactory.getLogger(CacheDataValue.class);
	/**
	 * 前值
	 */
	private HashMap<String, List> beforeValues;

	/**
	 * 后值
	 */
	private HashMap<String, List> afterValues;

	/**
	 * 参数值
	 */
	private HashMap<Integer, Object> args;

	/**
	 * 返回值
	 */
	private Object result;

	/**
	 * 类属性值
	 */
	private Object thisClassValue;
	public CacheDataValue(){}
	public CacheDataValue(HashMap<String, List> beforeValues,
			HashMap<Integer, Object> args, Object result, Object thisClassValue) {
		super();
		this.beforeValues = beforeValues;
		this.args = args;
		this.result = result;
		this.thisClassValue = thisClassValue;
	}

	public HashMap<String, List> getBeforeValues() {
		return beforeValues;
	}

	public void setBeforeValues(HashMap<String, List> beforeValues) {
		this.beforeValues = beforeValues;
	}

	public HashMap<String, List> getAfterValues() {
		return afterValues;
	}

	public void setAfterValues(HashMap<String, List> afterValues) {
		this.afterValues = afterValues;
	}

	public HashMap<Integer, Object> getArgs() {
		return args;
	}

	public void setArgs(HashMap<Integer, Object> args) {
		this.args = args;
	}

	public Object getResult() {
		return result;
	}

	public void setResult(Object result) {
		this.result = result;
	}

	public Object getThisClassValue() {
		return thisClassValue;
	}

	public void setThisClassValue(Object thisClassValue) {
		this.thisClassValue = thisClassValue;
	}

	public HashMap<String, Object> initKeyValue(List<QueryValueBean> queryKeys) {
		HashMap<String, Object> keyValues = new HashMap<String, Object>();
		for (QueryValueBean queryBean : queryKeys) {
			String key = queryBean.getKey();
			String expr = queryBean.getExpr();
			QueryValueType valueType = queryBean.getQueryValueType();
			Object value = null;
			if (valueType.equals(QueryValueType.arg)) {
				value = parseArgsValue(this.args, expr);
			}
			else if (valueType.equals(QueryValueType.classValue)) {
                 value = parseReturnOrClassValue(this.thisClassValue, expr);
			}
			else if (valueType.equals(QueryValueType.returnValue)) {
				 value = parseReturnOrClassValue(this.result, expr);
			}
			else if(valueType.equals(QueryValueType.cons)){
				 value = expr;
			}
			keyValues.put(key, value);
		}
		return keyValues;
	}

	public String initValue(List<RecordValueBean> recordValueBeans) {
		StringBuffer value = new StringBuffer();
		// 最终产生的值以key=value<$CDATA>key=value<$CDATA>的形式产生
		for (RecordValueBean recordValue : recordValueBeans) {
			String valueResult = null;
			String key = recordValue.getKey();
			ValueType valueType = recordValue.getValueType();
			String expr = recordValue.getExpr();
			Object obj = null;
			try{
			if (valueType.equals(ValueType.arg)) {
				obj = parseArgsValue(this.args, expr);
			} else if (valueType.equals(ValueType.classValue)) {
				obj = parseReturnOrClassValue(this.thisClassValue, expr);
			} else if (valueType.equals(ValueType.returnValue)) {
			    obj = parseReturnOrClassValue(this.result, expr);
			} else if (valueType.equals(ValueType.beforeValue)) {
				obj =  parseBeforeOrAfterValue(this.beforeValues, expr);
			} else if (valueType.equals(valueType.afterValue)) {
			    obj = parseBeforeOrAfterValue(this.afterValues, expr);
			}
			}catch(Exception e){
				logger.error("Record Value Parse Error:key="+recordValue.getKey());
			}
			if(obj!=null)valueResult = parseToString(obj);
			value.append(key + SpecialValue.VALUE_EQUAL + valueResult +SpecialValue.VALUE_SPLIT);
		}
		return value.toString();
	}

	/**
	 * 解析出返回或类值
	 * 
	 * @param obj
	 * @param expr
	 * @return
	 */
	private Object parseReturnOrClassValue(Object obj, String expr) {
		return ObjectValueReflection.reflectObjectValueString(expr, obj);
	}

	/**
	 * 解析出参数值
	 * 
	 * @param obj
	 * @param expr
	 * @return
	 */
	private Object parseArgsValue(HashMap<Integer, Object> args, String expr) {
		// args[0].xxxx.xxx, args[1].xxx.xxx类似

		int index = Integer.parseInt(expr.substring(expr.indexOf("[") + 1,
				expr.indexOf("]")));
		Object obj = args.get(index);
		if(!expr.contains("."))return obj;
		String newExpr = expr.substring(expr.indexOf("]") + 2);
		obj = ObjectValueReflection.reflectObjectValueString(newExpr, obj);
		return obj;
	}

	/**
	 * 解析出前值或后值
	 * 
	 * @param obj
	 * @param expr
	 * @return
	 */
	private Object parseBeforeOrAfterValue(HashMap<String, List> values,
			String expr) {
		// FlightSchdule.flightId
		String entityName = expr.substring(0, expr.indexOf("."));
		String newExpr = expr.substring(expr.indexOf(".") + 1);
		if (values.containsKey(entityName)) {
			Object obj = values.get(entityName);
			obj = ObjectValueReflection.reflectObjectValueString(newExpr, obj);
			return obj;
		}
		return null;
	}

	public static void main(String args[]) {
		List<String> testList = new ArrayList<String>();
		testList.add("123");
		testList.add("abc");
		testList.add("=");
		System.out.println(parseToString(testList));
		
		String[] arr = new String[]{"abc","dfa"};
		System.out.println(parseToString(arr));
	}
	
	private static String parseToString(Object obj){
		if(obj instanceof Collection){
			Collection objCollection = (Collection)(obj);
			String parseValue = "";
			for(Object val:objCollection){
				if(val==null)continue;
				parseValue = parseValue +val.toString()+ SpecialValue.VALUE_PERIOD;
			}
			return parseValue;
		}
		if(obj instanceof Object[]){
			Object[] objCollection = (Object[])(obj);
			String parseValue = "";
        	for(Object val:objCollection){
        		if(val==null)continue;
        		parseValue = parseValue +val.toString()+SpecialValue.VALUE_PERIOD;
        	}
        	return parseValue;
		}
		return obj.toString();
	}
	
	
}
